package model.entity.brain;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.HashMap;

import main.Log;
import model.Executable;
import model.GameClock;
import model.entity.*;
import model.handler.MovementHandler;
import model.map.Direction;
import model.map.GameMap;
import model.map.HexLocationProjection;
import model.map.Location;
import model.map.LocationProjection;
import model.map.Obstacle;
import model.map.World;
import utilities.*;

public class PetBrain extends Brain implements Archiveable {
	private Location avatarLoc;
	private BasicEntity npc;
	private GameMap gameMap;
	private PetState petState;
	private Map<String, PetState> nextState;

	
	public PetBrain(Avatar av, BasicEntity ent, GameMap gm){
		avatarLoc = av.getLocation();
		npc = ent;
		gameMap = gm;
		petState = new BehaveState();
		//nextState = new HashMap<String, PetState>();
		//nextState.put("Behave", new MisbehaveState());
		//nextState.put("MisBehave", new BehaveState());
		
		
		GameClock.getInstance().schedule(40, new Executable() {
			public void execute() { start(); }
		});
		
	}
	
	public PetBrain() {
		// TODO Auto-generated constructor stub
	}

	public void cancelBrainFunctioning() {
		
	}
	
	/**
	 * for adding states to our state transition map
	 * @param stateName
	 * @param theNextState
	 */
	/*
	public void addState(String stateName, PetState theNextState){
		nextState.put(stateName, theNextState);
	}
	*/
	
	/**
	 * for swapping between states
	 * @param pState
	 */
	private void changeState(){
		//petState = nextState.get(petState.getName());
		
		
		if(petState.getName() == "Behave"){
			petState = new MisbehaveState();
		}
		else if(petState.getName() == "Misbehave"){
			petState = new BehaveState();
		}
		
	}
	
	public void start(){
		
		MovementHandler mh = MovementHandler.getInstance();
		mh.moveEntity(npc, getNextMove());
		
		// every so often calculate the move
		final GameClock c = GameClock.getInstance();
		c.scheduleAtFixedRate( 10, new Executable() {
			public void execute() {
				MovementHandler mh = MovementHandler.getInstance();
				mh.moveEntity(npc, getNextMove());
			}
		} );
		
		
		// every 30 seconds change state 
		c.scheduleAtFixedRate( 800, new Executable() {
			public void execute() {
				changeState();
				//Log.out(Log.MODEL, "state:" + petState.getName());
			}
		} );
		
		
	}
	
	/**
	 * move in the direction of the Avatar
	 * @return
	 */
	private Direction getNextMove(){
		gameMap = World.getInstance().getCurrentMap();
//		System.out.println("gameMap:" + gameMap);
//		System.out.println("gameMap:" + npc);
//		System.out.println("gameMap:" + avatarLoc);
		return petState.getNextMove(npc, avatarLoc, gameMap);
	}
	
	public Archive save() {
		Archive archive = super.save();
		
//		archive.putClassName("avatarLoc", this.avatarLoc.getClass().getName());
//		archive.putOneRelationship("avatarLoc", this.avatarLoc);
//		
//		List<String> nextStateClassList = new ArrayList<String>();
//		List<String> nextStateKeys = new ArrayList<String>(this.nextState.keySet());
//		Collections.sort(nextStateKeys);
//		List<PetState> nextStateValues = new ArrayList<PetState>(this.nextState.size());
//		for (int i = 0; i < this.nextState.size(); i++) {
//			String aKey = nextStateKeys.get(i);
//			PetState aValue = this.nextState.get(aKey);
//			nextStateClassList.add(aValue.getClass().getName());
//		}
//		archive.putAttributeList("nextStateClassList", nextStateClassList);
//		archive.putAttributeList("nextStateKeys", nextStateKeys);
//		archive.putManyRelationship("nextStateValues", nextStateValues);
//		
//		archive.putClassName("petState", this.petState.getClass().getName());
//		archive.putOneRelationship("petState", this.petState);
		
		return archive;
	}
	
	public void load(Archive archive) {
		super.load(archive);
		
//		this.avatarLoc = (Location)ModelFactory.getInstance().createInstanceWithClassName("avatarLoc");
//		this.avatarLoc.load(archive.getOneRelationship("avatarLoc"));
//		
//		this.nextState = new HashMap<String, PetState>();
//		List<String> nextStateClassList = archive.getAttributeList("nextStateClassList");
//		List<String> nextStateKeys = archive.getAttributeList("nextStateKeys");
//		List<Archive> nextStateValues = archive.getManyRelationship("nextStateValues");
//		for (int i = 0; i < nextStateClassList.size(); i++) {
//			String key = nextStateKeys.get(i);
//			PetState state = (PetState)ModelFactory.getInstance().createInstanceWithClassName(nextStateClassList.get(i));
//			state.load(nextStateValues.get(i));
//			this.nextState.put(key, state);
//		}
//		
//		this.petState = (PetState)ModelFactory.getInstance().createInstanceWithClassName("petState");
//		this.petState.load(archive.getOneRelationship("petState"));
	}

}